Skip to content

Conversation

fabik111
Copy link
Contributor

@fabik111 fabik111 commented Oct 7, 2025

The PR #402 introduces crashes on the Opta device if using BLE and Ethernet together.
This is due to the mbed::CriticalSectionLock critical_section; RAII mechanism inside the HCICordioTransportClass::handleRxData function. This function on Opta and Portenta H7 is executed within an ISR context, so the critical section statement is not needed and can cause crashes if used with the Ethernet enabled.

This PR addresses the problem by entering the critical section only for the Nano 33 BLE or Nano 33 BLE Sense boards.

Copy link

codecov bot commented Oct 7, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 15.25%. Comparing base (23acde3) to head (b65c91a).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #412   +/-   ##
=======================================
  Coverage   15.25%   15.25%           
=======================================
  Files          29       29           
  Lines        3685     3685           
=======================================
  Hits          562      562           
  Misses       3123     3123           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

github-actions bot commented Oct 7, 2025

Memory usage change @ b65c91a

Board flash % RAM for global variables %
arduino:mbed_nano:nano33ble 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:mbed_nano:nanorp2040connect 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:megaavr:uno2018:mode=on 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:renesas_uno:unor4wifi 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:samd:mkrwifi1010 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
arduino:samd:nano_33_iot 0 - 0 0.0 - 0.0 0 - 0 0.0 - 0.0
Click for full report table
Board examples/Central/LedControl
flash
% examples/Central/LedControl
RAM for global variables
% examples/Central/PeripheralExplorer
flash
% examples/Central/PeripheralExplorer
RAM for global variables
% examples/Central/Scan
flash
% examples/Central/Scan
RAM for global variables
% examples/Central/ScanCallback
flash
% examples/Central/ScanCallback
RAM for global variables
% examples/Central/SensorTagButton
flash
% examples/Central/SensorTagButton
RAM for global variables
% examples/Peripheral/Advertising/EnhancedAdvertising
flash
% examples/Peripheral/Advertising/EnhancedAdvertising
RAM for global variables
% examples/Peripheral/Advertising/RawDataAdvertising
flash
% examples/Peripheral/Advertising/RawDataAdvertising
RAM for global variables
% examples/Peripheral/BatteryMonitor
flash
% examples/Peripheral/BatteryMonitor
RAM for global variables
% examples/Peripheral/ButtonLED
flash
% examples/Peripheral/ButtonLED
RAM for global variables
% examples/Peripheral/CallbackLED
flash
% examples/Peripheral/CallbackLED
RAM for global variables
% examples/Peripheral/EncryptedBatteryMonitor
flash
% examples/Peripheral/EncryptedBatteryMonitor
RAM for global variables
% examples/Peripheral/LED
flash
% examples/Peripheral/LED
RAM for global variables
%
arduino:mbed_nano:nano33ble 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
arduino:mbed_nano:nanorp2040connect 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
arduino:megaavr:uno2018:mode=on 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
arduino:renesas_uno:unor4wifi 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
arduino:samd:mkrwifi1010 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
arduino:samd:nano_33_iot 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0
Click for full report CSV
Board,examples/Central/LedControl<br>flash,%,examples/Central/LedControl<br>RAM for global variables,%,examples/Central/PeripheralExplorer<br>flash,%,examples/Central/PeripheralExplorer<br>RAM for global variables,%,examples/Central/Scan<br>flash,%,examples/Central/Scan<br>RAM for global variables,%,examples/Central/ScanCallback<br>flash,%,examples/Central/ScanCallback<br>RAM for global variables,%,examples/Central/SensorTagButton<br>flash,%,examples/Central/SensorTagButton<br>RAM for global variables,%,examples/Peripheral/Advertising/EnhancedAdvertising<br>flash,%,examples/Peripheral/Advertising/EnhancedAdvertising<br>RAM for global variables,%,examples/Peripheral/Advertising/RawDataAdvertising<br>flash,%,examples/Peripheral/Advertising/RawDataAdvertising<br>RAM for global variables,%,examples/Peripheral/BatteryMonitor<br>flash,%,examples/Peripheral/BatteryMonitor<br>RAM for global variables,%,examples/Peripheral/ButtonLED<br>flash,%,examples/Peripheral/ButtonLED<br>RAM for global variables,%,examples/Peripheral/CallbackLED<br>flash,%,examples/Peripheral/CallbackLED<br>RAM for global variables,%,examples/Peripheral/EncryptedBatteryMonitor<br>flash,%,examples/Peripheral/EncryptedBatteryMonitor<br>RAM for global variables,%,examples/Peripheral/LED<br>flash,%,examples/Peripheral/LED<br>RAM for global variables,%
arduino:mbed_nano:nano33ble,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0
arduino:mbed_nano:nanorp2040connect,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0
arduino:megaavr:uno2018:mode=on,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0
arduino:renesas_uno:unor4wifi,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0
arduino:samd:mkrwifi1010,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0
arduino:samd:nano_33_iot,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0,0,0.0

@per1234 per1234 added type: imperfection Perceived defect in any part of project topic: code Related to content of the project itself labels Oct 7, 2025
@sebromero
Copy link
Contributor

Hi @fabik111 ! PR #402 fixed a nasty issue with corrupted BLE frames on Opta that we were experiencing. It might just be a side effect of the lock that it somehow prevents a race condition. We must investigate this and find a different solution for that problem before we can merge this PR.

@sebromero
Copy link
Contributor

@fabik111 If you like you can try to reproduce the frame corruption. If you have another Arduino board, just send the same BLE advertising frame over and over and check the bytes on the receiver (Opta). Pre #402 at some point you will read a corrupted frame.

@fabik111
Copy link
Contributor Author

fabik111 commented Oct 16, 2025

Hello @sebromero, thank you for your reply.
The PR doesn't disable all the fixes of #402, but only the critical section in the HCICordioTransportClass::handleRxData function. This function in Opta and Portenta H7 is passed as a callback for an IRQ.
The HCICordioTransportClass::handleRxData is called inside HCICordioTransportClass::onDataReceived, which is passed as a callback with the CordioHCIHook::setDataReceivedHandler function in the begin. The CordioHCIHook::setDataReceivedHandler implementation is here and calls the set_data_received_handler function of the driver instance of mbed-os passing the callback function.

The implementation of set_data_received_handler is here and you can see that assigns the callback to a local variable data_received_handler.
This variable is used in the CordioHCITransportDriver::on_data_received.

The CordioHCITransportDriver::on_data_received is called inside the CyH4TransportDriver::on_controller_irq of the CYW43XXX driver.

So at run time, the HCICordioTransportClass::handleRxData function should be executed inside an ISR in which, in theory, there is no need to enter the critical section because it is already a "special" execution mode of the processor that "suspends" other threads.

Did you test this PR, and did you encounter the same problem you had previously the #402?

If you like you can try to reproduce the frame corruption.

Yes, I will do.

If you have another Arduino board, just send the same BLE advertising frame over and over and check the bytes on the receiver (Opta)

Just for clarification, the Opta was in central mode, and it was continuously scanning for advertising messages that were coming from another Arduino board?
What was the payload? How long was it? And in which section of the advertising messages was the data? Device Name, Manufacturer section, Services.....

@sebromero
Copy link
Contributor

@fabik111 I'm reading data from a BLE sensor on the Opta. Here is my test sketch that I used:

#include <ArduinoBLE.h>

static constexpr uint8_t SENSOR_INFO_TEMP_OFFSET = 19;
static constexpr uint8_t SENSOR_INFO_HUM_OFFSET = 21;
static constexpr uint8_t SENSOR_INFO_ACCELERATION_OFFSET = 13;


inline int16_t convertToInt16(uint8_t* data, uint8_t offset){
    return (int16_t)((uint16_t)data[offset] << 8 | data[offset + 1]);
}
inline uint16_t convertToUInt16(uint8_t* data, uint8_t offset){
    return (uint16_t)((uint16_t)data[offset] << 8 | data[offset + 1]);
}

void blinkLED(int pin, int times = 5, int delayTime = 200) {
    for (int i = 0; i < times; i++) {
        digitalWrite(pin, !digitalRead(pin));
        delay(delayTime);
        digitalWrite(pin, !digitalRead(pin));
        delay(delayTime);
    }
}


String frameToString(uint8_t* adv_data, uint8_t data_length) {
    // Returns a string representation of the frame type as a list of 0xXX hex values
    String result;
    for (int i = 0; i < data_length; i++) {
        result += String(adv_data[i], HEX);
        if (i < data_length - 1) {
            result += " ";
        }
    }
    return result;
}


void setup() {
    Serial.begin(115200);
    pinMode(LEDR, OUTPUT);
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(LED_USER, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(LEDR, LOW);
    digitalWrite(LED_USER, LOW);
    
    // Wait 5 seconds for Serial connection before continuing
    for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000););

    if (!BLE.begin()) {
        Serial.println("Starting Bluetooth® Low Energy module failed!");
        while (1);
    }

    digitalWrite(LED_BUILTIN, HIGH);
    Serial.println("Starting BLE scan...");
    BLE.scan(true);
}

void loop() {
    BLEDevice device = BLE.available();
    if (!device) return;
    
    int len = device.advertisementDataLength();

    if(len < 8){
        // Doesn't seem to be a valid frame type, can't check anyway with just 8 bytes
        return;
    }

    uint8_t data[62];
    device.advertisementData(data, len);    

    // Check for service UUID
    if(!(data[5] == 0x01 && data[6] == 0xEA)) return;

    // Check for specific frame
    if(data[7] != 0x80) return;

    if(len > 62){
        digitalWrite(LED_USER, HIGH);
        Serial.println(String("Invalid advertisement data length: ") + String(len));
        return;
    }

    // Make sure the data is long enough to contain the field with the highest offset
    if(len < SENSOR_INFO_HUM_OFFSET + 2){
        digitalWrite(LED_USER, HIGH);
        Serial.println(String("Advertisement data length too short: ") + String(len));
        return;
    }

    int16_t temperatureRaw = convertToInt16(data, SENSOR_INFO_TEMP_OFFSET);
    uint16_t humidityRaw = convertToUInt16(data, SENSOR_INFO_HUM_OFFSET);
    int16_t accelerationXRaw = convertToInt16(data, SENSOR_INFO_ACCELERATION_OFFSET);
    int16_t accelerationYRaw = convertToInt16(data, SENSOR_INFO_ACCELERATION_OFFSET + 2);
    int16_t accelerationZRaw = convertToInt16(data, SENSOR_INFO_ACCELERATION_OFFSET + 4);

    float temperature = temperatureRaw / 10.0;
    float humidity = humidityRaw / 10.0;
    float accelerationX = accelerationXRaw / 1000.0;
    float accelerationY = accelerationYRaw / 1000.0;
    float accelerationZ = accelerationZRaw / 1000.0;

    // Serial.print(device.address());
    // if (device.hasLocalName()) {
    //     Serial.print(" ");
    //     Serial.print(device.localName());
    // }
    // Serial.println();
    // Serial.print("T: ");
    // Serial.print(temperature);
    // Serial.print(" H: ");
    // Serial.println(humidity);
    // Serial.print("X: ");
    // Serial.print(accelerationX);
    // Serial.print(" Y: ");
    // Serial.print(accelerationY);
    // Serial.print(" Z: ");
    // Serial.println(accelerationZ);

    if(temperature < -20 || temperature > 85){
        digitalWrite(LED_USER, HIGH);
        Serial.println(String("Invalid temperature value: ") + String(temperature));
        Serial.println(String("Frame data: ") + frameToString(data, len));
    }

    if(humidity < 0 || humidity > 100){
        digitalWrite(LED_USER, HIGH);
        Serial.println(String("Invalid humidity value: ") + String(humidity));
        Serial.println(String("Frame data: ") + frameToString(data, len));
    }

    if(accelerationX < -2 || accelerationX > 2){
        digitalWrite(LED_USER, HIGH);
        Serial.println(String("Invalid X acceleration value: ") + String(accelerationX));
        Serial.println(String("Frame data: ") + frameToString(data, len));
    }
    if(accelerationY < -2 || accelerationY > 2){
        digitalWrite(LED_USER, HIGH);
        Serial.println(String("Invalid Y acceleration value: ") + String(accelerationY));
        Serial.println(String("Frame data: ") + frameToString(data, len));
    }
    if(accelerationZ < -2 || accelerationZ > 2){
        digitalWrite(LED_USER, HIGH);
        Serial.println(String("Invalid Z acceleration value: ") + String(accelerationZ));
        Serial.println(String("Frame data: ") + frameToString(data, len));
    }
    // Serial.println("---");
}

@sebromero
Copy link
Contributor

@fabik111 If you want to test this, you can use this simulator sketch:

#include <ArduinoBLE.h>

#if defined(ARDUINO_ARDUINO_NANO33BLE)
    #include <Arduino_HTS221.h>
    #include <Arduino_LSM9DS1.h>
#elif defined(ARDUINO_NICLA)
    #include "Arduino_BHY2.h"
    SensorXYZ accelerometer(SENSOR_ID_ACC);
    Sensor temperatureSensor(SENSOR_ID_TEMP);
    Sensor humiditySensor(SENSOR_ID_HUM); 
#endif

#define SENSOR_INFO_TEMP_OFFSET 19
#define SENSOR_INFO_HUM_OFFSET 21
#define SENSOR_INFO_ACCELERATION_OFFSET 13

// Advertising parameters should have a global scope. Do NOT define them in 'setup' or in 'loop'
uint8_t completeRawAdvertisingData[] = {
    0x02, // Length of this AD structure (2 bytes follow)
    0x01, // AD type = Flags
    0x06, // Flags = LE General Discoverable Mode | BR/EDR Not Supported
    0x1B, // Length of this AD structure (27 bytes follow)
    0x16, // AD type = Service UUID
    0x01, 0xEA, // Service UUID = 0x0101EA
    0x80, // Frame type UUID: 0x80
    0b10111100, // Sensor status
    0x0, // MAGNET_CNT_LSB
    0x0, // MAGNET_CNT_MSB
    0x0, // MOTION_CNT_LSB
    0x0, // MOTION_CNT_MSB
    0x0, // Accel.Dat_X axis (mg) LSB
    0x0, // Accel.Dat_X axis (mg) MSB
    0x0, // Accel.Dat_Y axis (mg) LSB
    0x0, // Accel.Dat_Y axis (mg) MSB
    0x0, // Accel.Dat_Z axis (mg) LSB
    0x0, // Accel.Dat_Z axis (mg) MSB
    0x0, // Temperature.Dat (C) LSB
    0x0, // Temperature.Dat (C) MSB
    0x0, // Humidity.Dat (%RH) LSB
    0x0, // Humidity.Dat (%RH) MSB
    0x0, // Battery percentage(1%) / Battery voltage (1mV)_LSB
    0x64, // Battery percentage(1%) / Battery voltage (1mV)_MSB
    0x0, // Tag ID[0]
    0x0, // Tag ID[1]
    0x0, // Tag ID[2]
    0x0, // Tag ID[3]
    0x0, // Tag ID[4]
    0x0  // Tag ID[5]
};

BLEAdvertisingData advData;

void updateTemperatureHumidity() {
  #if defined(ARDUINO_ARDUINO_NANO33BLE)
    float temperature = HTS.readTemperature();
    float humidity = HTS.readHumidity();
  #elif defined(ARDUINO_NICLA)
    float temperature = temperatureSensor.value();
    float humidity = humiditySensor.value();
    if(!temperatureSensor.dataAvailable() || !humiditySensor.dataAvailable()) {
        Serial.println("Temperature or humidity sensor not available");
        return;
    }
  #else
    // Generate random values for other boards (range 20-25 °C and 20-80 %RH)
    float temperature = random(200, 250) / 10.0;
    float humidity = random(200, 800) / 10.0;
  #endif

  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.print(" °C, Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");

  uint16_t convertedTemperature = (uint16_t)(temperature * 10); // Convert to tenths of degree
  uint16_t convertedHumidity = (uint16_t)(humidity * 10); // Convert to tenths of percent

  completeRawAdvertisingData[SENSOR_INFO_TEMP_OFFSET] = highByte(convertedTemperature);
  completeRawAdvertisingData[SENSOR_INFO_TEMP_OFFSET + 1] = lowByte(convertedTemperature);
  completeRawAdvertisingData[SENSOR_INFO_HUM_OFFSET] = highByte(convertedHumidity);
  completeRawAdvertisingData[SENSOR_INFO_HUM_OFFSET + 1] = lowByte(convertedHumidity);
}

void updateIMU(){
    #if defined(ARDUINO_ARDUINO_NANO33BLE)
    float x, y, z;
    if (IMU.accelerationAvailable()){
        IMU.readAcceleration(x, y, z);
    }
    int16_t accelX = (int16_t)(x * 1000); // Convert to milligravity
    int16_t accelY = (int16_t)(y * 1000); // Convert to milligravity
    int16_t accelZ = (int16_t)(z * 1000); // Convert to milligravity
    #elif defined(ARDUINO_NICLA)
    if(!accelerometer.dataAvailable()) {
        Serial.println("Accelerometer not available");
        return;
    }
    int16_t accelX = accelerometer.x();
    int16_t accelY = accelerometer.y();
    int16_t accelZ = accelerometer.z();
    #else
    // Generate random values for other boards (range -2000 to 2000 mg)
    int16_t accelX = random(-2000, 2000);
    int16_t accelY = random(-2000, 2000);
    int16_t accelZ = random(-2000, 2000);
    #endif

    Serial.print("Acceleration X: ");
    Serial.print(accelX / 1000.0); // Convert to g
    Serial.print(" Y: ");
    Serial.print(accelY / 1000.0); // Convert to g
    Serial.print(" Z: ");
    Serial.println(accelZ / 1000.0); // Convert to g
    
    completeRawAdvertisingData[SENSOR_INFO_ACCELERATION_OFFSET] = highByte(accelX);
    completeRawAdvertisingData[SENSOR_INFO_ACCELERATION_OFFSET + 1] = lowByte(accelX);
    completeRawAdvertisingData[SENSOR_INFO_ACCELERATION_OFFSET + 2] = highByte(accelY);
    completeRawAdvertisingData[SENSOR_INFO_ACCELERATION_OFFSET + 3] = lowByte(accelY);
    completeRawAdvertisingData[SENSOR_INFO_ACCELERATION_OFFSET + 4] = highByte(accelZ);
    completeRawAdvertisingData[SENSOR_INFO_ACCELERATION_OFFSET + 5] = lowByte(accelZ);
}

void updateMACAddress() {
    String address = BLE.address();
    uint8_t addr[6];
    int idx = 0;
    for (int i = 0; i < address.length(); i += 3) {
        String byteStr = address.substring(i, i + 2);
        addr[idx++] = (uint8_t)std::strtol(byteStr.c_str(), nullptr, 16);
    }
    // Update the Tag ID in the advertising data with the MAC address
    for (int i = 0; i < 6; i++) {
        completeRawAdvertisingData[25 + i] = addr[i];
    }
}

void updateSensorData() {
    updateTemperatureHumidity();
    updateIMU();
}

void startSensors(){
  #if defined(ARDUINO_ARDUINO_NANO33BLE)
    HTS.begin();
    IMU.begin();
  #elif defined(ARDUINO_NICLA)
    BHY2.begin();
    temperatureSensor.begin();
    humiditySensor.begin();
    accelerometer.begin();
  #endif
}

void setup() {
  startSensors();
  
  Serial.begin(9600);
  // Wait for 5 seconds to allow the serial monitor to connect
  for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000););

  // Blink to indicate the start of the program
  for (int i = 0; i < 5; i++) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(100);
    digitalWrite(LED_BUILTIN, LOW);
    delay(100);
  }

  if (!BLE.begin()) {
    Serial.println("failed to initialize BLE!");
    while (1);
  }

  updateMACAddress(); // Update MAC address from the board's BLE address
  updateSensorData(); // Initial sensor data update
  advData.setRawData(completeRawAdvertisingData, sizeof(completeRawAdvertisingData));  
  BLE.setAdvertisingData(advData);
  BLEAdvertisingData scanData; // Build scan response data packet
  scanData.setLocalName("MK Simulator");
  BLE.setScanResponseData(scanData); // Copy set parameters in the actual scan response packet
  BLE.setAdvertisingInterval(1000); // ms, default is 100ms

  BLE.advertise();
  Serial.println("Advertising at " + String(BLE.address()));
}

void loop() {
  #if defined(ARDUINO_NICLA)
    BHY2.update();
  #endif
  BLE.poll();

  static unsigned long lastUpdate = 0;
  unsigned long currentMillis = millis();
    if (currentMillis - lastUpdate >= 1000) { // Update every second
        lastUpdate = currentMillis;
        BLE.stopAdvertise(); // Stop advertising to update data
        updateSensorData(); // Update sensor data
        BLE.advertise();
    }
}

@fabik111
Copy link
Contributor Author

@sebromero, I ran your code, and I didn't find differences in the execution between the master version and the version of this PR.

@sebromero
Copy link
Contributor

@fabik111 thank you for testing! I'm running a test as well. Sometimes it takes hours or even a day or two until the data corruption occurs. I'll let you know about my result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: code Related to content of the project itself type: imperfection Perceived defect in any part of project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants